<?php

/**
 * 转写文件
 */

namespace app\api\controller;

use app\common\controller\Common;
use think\Db;
use app\common\MixDataHandle;
use app\common\Content;


class Speech extends Base
{
    protected $model;
    public function _initialize()
    {
        parent::_initialize();
        $this->model = Model('LiveSpeech1');
    }

    /**
     * 文件列表
     */
    public function list($start_time = 0, $end_time = 9999999999, $match = "", $limit = 10, $page = 1)
    {
        $map = [
            'is_delete' => 0,
            'a.start_time' => ['between', [$start_time ? $start_time : 0, $end_time ? $end_time : 9999999999]],
            //模糊匹配
            'a.filename|u.username|e.title' => ['like', '%' . trim($match) . '%']
        ];
        if (isset($GLOBALS['userInfo'])) {
            if ($GLOBALS['userInfo']['user_group'] !== 16 && $GLOBALS['userInfo']['user_group'] !== 1) {
                $map['uid'] = $GLOBALS['userInfo']['id'];
            }
        }
        $result = $this->model->getList($map, $limit, $page);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => $result]);
    }

    /**
     * 备注信息添加
     */
    public function editCommit()
    {
        if (!$this->param['id']) {
            return resultArray(['error' => '未添加文件id']);
        }
        $result = $this->model->updateDataById(['notes'  => $this->param['notes']], $this->param['id']);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => '']);
    }


    /**
     * 上传音频
     */
    public function audioUpload()
    {
        if (!$this->param['id']) {
            return resultArray(['error' => '未添加用户id']);
        }
        $dir = config('huisheng.upload_audio_dir');
        if (!is_dir($dir)) {
            @mkdir($dir, 0777, true);
        }
        //记录文件,判断是否为同一个文件
        if (!cache('uploadfile-' . $this->param['id'] . '-' . $this->param['identifier'])) {
            $filename = (md5(uniqid($this->param['id']))) . "." . pathinfo($this->param['filename'])['extension'];
            cache('uploadfile-' . $this->param['id'] . '-' . $this->param['identifier'], $filename, 3600);
        } else {
            $filename = cache('uploadfile-' . $this->param['id'] . '-' . $this->param['identifier']);
        }
        if (burstUpload($dir, $filename) === true) {
            cache('uploadfile-' . $this->param['id'] . '-' . $this->param['identifier'], null);
            $param = [
                'uid' => $this->param['id'],
                'did' => 0,
                'filename' => $_FILES['file']['name'],
                'formatname' => pathinfo($filename)['filename'],
                'size' => @filesize($dir . DS . $filename) ? filesize($dir . DS . $filename) : 0,
                'start_time' => time(), 'create_time' => time(), 'update_time' => time(),
                'is_manual' => 2,
                'transition_state' => 0,
            ];
            $param['meeting_tag'] = $GLOBALS['userInfo']['username'] . '-0-' .  pathinfo($filename)['filename'];
            $result_id = $this->model->createFileData($param);
            if (!$result_id) {
                unlink($dir . DS . $filename);
                return resultArray(['error' => $this->model->getError()]);
            }
        } else if (burstUpload($dir, $filename) === false) {
            return resultArray(['error' => '上传错误']);
        }
    }

    public function transferTragger($id)
    {
        if (!$id) {
            return resultArray(['error' => 'id为空']);
        }
        $file = $this->model->get($id);
        if ($file->transition_state == 1 || $file->transition_state == 2) {
            return resultArray(['data' => '']);
        }
        $formatname = $file->formatname;
        $uid = $file->uid;
        $dir = config('huisheng.upload_audio_dir') . DS . $formatname;
        $ext = pathinfo($file->filename)['extension'];
        $filename = "$formatname.$ext";
        $push_array = [
            'type' => 1,
            'id' => $id,
            'ori_path' => $dir . DS . $filename,
            'des_path' => config('huisheng.box_audio_dir') . DS . $formatname . ".wav",
        ];
        self::$redis->pushUploadFileQueue($push_array);
        $file->transition_state = 1;
        $file->update_time = time();
        $file->save();
        return resultArray(['data' => '']);
    }



    /**
     * 删除文件
     * @file_id      文件id
     * @user_id     操作人id
     */
    public function delete($id)
    {
        //首先拿到文件file_id
        if (empty($id)) {
            return resultArray(['error' => '参数不能为空']);
        }
        $result = $this->model->updateDataById(['is_delete' => 1, 'update_time' => time()], $id);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => '']);
    }

    /**
     * 批量删除文件
     * @id 字符串数组
     * @delSure  全删参数 true则不管有没有id都删光全部文件
     */
    public function batchDelete($ids)
    {
        //获取id数组
        if (empty($ids)) {
            return resultArray(['error' => '批量删除参数为空']);
        }
        $result = $this->model->deletDatas($ids);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => '']);
    }

    /**
     * 回收站文件列表
     * @limit 分页每页数量
     * @page 分页页数
     */
    public function delList($limit = '10', $page = '1')
    {
        if (isset($GLOBALS['userInfo'])) {
            if ($GLOBALS['userInfo']['user_group'] !== 16) {
                $map['uid'] = $GLOBALS['userInfo']['id'];
            }
        }
        $map['is_delete'] = 1;
        $result = $this->model->getdelList($map, $limit, $page);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => $result]);
    }

    /**
     * 还原回收站中的文件
     * @sfrid 回收站文件id
     */
    public function restore($sfrid = '')
    {
        if (empty($sfrid)) {
            return resultArray(['error' => '参数不能为空']);
        }
        $result = $this->model->updateDataById(['is_delete' => 0, 'update_time' => time()], $sfrid);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => '']);
    }

    /**
     * 批量还原回收站中的文件
     * @ids 批量还原回收站中文件的id，以,分割
     * @rtrAll 判断是否全部还原记号
     */
    public function batchRecycledRestore($ids = '', $rtrAll = false)
    {
        //启动事务
        DB::startTrans();
        try {
            //格式化字符串
            $id = explode(",", $ids);
            $speech = Model('LiveSpeech');
            if ($rtrAll) {
                $result = $speech->where(['is_delete' => 1])->update(['is_delete' => 0]);
            } else {
                $result = $speech->where(['is_delete' => 1])->where('id', 'in', $id)->update(['is_delete' => 0]);;
            }
            DB::commit();
            return resultArray(['data' => '']);
        } catch (\Exception $e) {
            DB::rollback();
            //return resultArray(['error' => $e->getMessage()]);
            return resultArray(['error' => '请求失败']);
        }
    }

    /**
     * 硬删除文件
     * @sfrid 回收站文件id
     */
    public function recycledDel($sfrid)
    {
        //启动事务
        Db::startTrans();
        try {
            $sfrid = input('param.sfrid');
            if (empty($sfrid)) {
                return resultArray(['error' => '参数错误']);
            }
            $speech = Model('LiveSpeech');
            $result = $speech->updateDataById(['is_delete' => 2], $sfrid);
            if (!$result) {
                return resultArray(['error' => $speech->getError()]);
            }
            $file = $speech->get($sfrid)->toArray();
            $path = config('huisheng.file_mp3_path') . DS . $file['user_id'] . DS . str_replace('.wav', '.mp3', $file['formatname']);
            $md5path = config('huisheng.file_mp3_path') . DS . $file['user_id'] . DS . str_replace('.wav', '.md5', $file['formatname']);
            if (is_file($path)) {
                @unlink($path);
                @unlink($md5path);
            }
            Db::commit();
            return resultArray(['data' => '']);
        } catch (\Exception $e) {
            Db::rollback();
            //return resultArray(['error' => $e->getMessage()]);
            return resultArray(['error' => '请求失败']);
        }
    }

    /**
     * 批量删除回收站中的文件
     * @ids 批量删除回收站中文件的id，以,分割
     * @rtrAll 判断是否全部删除记号
     */
    public function batchRecycledDel($ids = '', $delAll = 0)
    {
        //启动事务
        DB::startTrans();
        try {
            //格式化字符串
            $id = explode(",", $ids);
            $speech = Model('LiveSpeech');
            if ($delAll) {
                $all = $speech->where(['is_delete' => 1])->select();
            } else {
                $all = $speech->where(['is_delete' => 1])->select($id);
            }
            foreach ($all as $delete) {
                $folder = $delete['uid'];
                $filename = $delete['formatname'] . ".mp3";
                $jsonname = $delete['formatname'] . ".json";
                //检查文件是否存在
                $filepath = config('huisheng.file_mp3_path') . '/' . $folder . '/' . $filename;
                $jsonpath = config('huisheng.file_mp3_path') . '/' . $folder . '/' . $jsonname;
                //删除操作 操作成功删除文件
                if ($delete->save(['is_delete' => 2])) {
                    is_file($filepath) ? @unlink($filepath) : '';
                    is_file($jsonpath) ? @unlink($jsonpath) : '';
                }
            }
            DB::commit();
            return resultArray(['data' => '']);
        } catch (\Exception $e) {
            DB::rollback();
            //return resultArray(['error' => $e->getMessage()]);
            return resultArray(['error' => '请求失败']);
        }
    }


    /**
     * 转写文件编辑
     */
    public function contentEdit()
    {
        if (!$this->param['id']) {
            return resultArray(['error' => '未添加文件id']);
        }
        if (!$this->param['lvsr_data']) {
            return resultArray(['error' => '输入文件为空']);
        }
        $data['editor'] = json_encode(['list' => $this->param['lvsr_data']], JSON_UNESCAPED_UNICODE);
        $data['update_time'] = time();
        $result = $this->model->updateDataById($data, $this->param['id']);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => '']);
    }

    /**
     * 转写文件详情 (非分段)
     */
    public function detail()
    {
        if (!$this->param['id']) {
            return resultArray(['error' => '参数错误']);
        }
        $result = $this->model->getDetail($this->param['id']);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        //这一步是为了符合前端代码以后可以不用
        for ($i = 0; $i < count($result['lvsr_data']); $i++) {
            $result['lvsr_data'][$i]['id'] = $i;
        }
        return resultArray(['data' => $result]);
    }

    public function detailPiecewise()
    {
        if (!$this->param['id']) {
            return resultArray(['error' => '参数错误']);
        }
        $result = $this->model->getDetail($this->param['id'], 1);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        //这一步是为了符合前端代码以后可以不用
        for ($i = 0; $i < count($result['lvsr_data']); $i++) {
            $result['lvsr_data'][$i]['id'] = $i;
        }
        return resultArray(['data' => $result]);
    }

    /**
     * 语气词和原始文档操作开关
     */
    public function operat(int $id, int $mood_type=0, int $is_initial=0, int $sensitive_type=0)
    {
        try {
            $result = $this->model->get($id)->combination($mood_type, $is_initial, $sensitive_type);
            //这一步是为了符合前端代码以后可以不用
            for ($i = 0; $i < count($result); $i++) {
                $result[$i]['id'] = $i;
            }
            return resultArray(['data' => ['lvsr_data' => $result]]);
        } catch (\Exception $e) {
            return resultArray(['error' => '请求失败']);
        }
    }


    /**
     * 获取摘要
     */
    public function abstract()
    {
        if (!$this->param['id']) {
            return resultArray(['error' => '参数错误']);
        }
        $result = $this->model->getAbstract($this->param['id'], $this->param['content']);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => ['summary' => $result]]);
    }

    /**
     * 下载文件
     */
    public function download()
    {
        if (!$this->param['id'] || !$this->param['type']) {
            return resultArray(['error' => '参数错误']);
        }
        $args = ['title' => '', 'time' => '', 'address' => '', 'host' => '', 'record' => '', 'name' => '', 'remark' => '', 'data' => ''];
        $result = $this->model->getDownloadFile($this->param['id'], $this->param['type'], $args);
        if (!$result) {
            return resultArray(['error' => $this->model->getError()]);
        }
        download_result_one($result);
    }

    /**
     * 下载转写结果文本
     */
    public function getDownloadTxtPath()
    {
        try {
            //doc参数
            if (!$this->param['id']) {
                return resultArray(['error' => '参数错误,文件id为空']);
            }
            if($this->param['new']){
                $result = $this->model->get($this->param['id'])->downloadTxtNew($this->param['data']);
            }else{
                $result = $this->model->get($this->param['id'])->downloaTxt($this->param['data']);
            }
            return resultArray(['data' => ['path' => $result]]);
        } catch (\Exception $e) {
            //return resultArray(['error' => $e->getMessage()]);
            return resultArray(['error' => '请求错误']);
        }
    }

    /**
     * 兼容以前下载转写结果文本
     */
    public function getDownloadTxtPathNew()
    {
        try {
            //doc参数
            if (!$this->param['id']) {
                return resultArray(['error' => '参数错误,文件id为空']);
            }
            $result = $this->model->get($this->param['id'])->downloadTxtNew($this->param['data']);
            return resultArray(['data' => ['path' => $result]]);
        } catch (\Exception $e) {
            //return resultArray(['error' => $e->getTrace()]);
            return resultArray(['error' => '请求错误']);
        }
    }

    /**
     * 
     */
    public function downloadFile($path)
    {
        download_result_one($path);
    }

    /**
     * 查看已经转写的非实时结果
     */
    public function norealTransferResult($id)
    {
        $result = $this->model->getTransferResult($id);
        if ($result === false) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => ['lvsr_data' => $result]]);
    }

    /**
     * 将录音文件转成二进制格式
     */
    public function showwave()
    {
        $id = input('speechId/d');
        if (!$id) {
            return resultArray(['error' => '参数错误']);
        }
        $recorder = Db::name('meeting_live_speech')->where(array('id' => $id))->find();
        if (!$recorder) {
            return resultArray(['error' => '参数错误']);
        }
        $json = @file_get_contents("/home/wwwroot/default/data/speech2/" . $recorder['uid'] . "/" . $recorder['formatname'] . ".json");
        if ($recorder['is_manual'] == 2) {
            $json = @file_get_contents("/home/wwwroot/default/data/speech3/" . $recorder['uid'] . "/" . $recorder['formatname'] . ".json");
        }
        if (!$json) {
            return resultArray(['data' => [0]]);
        }
        //header('content-type:text/html');
        //header("Content-Encoding: gzip");
        //return json_encode(array(123));exit;
        // return json(array(123),200,array('Content-Encoding'=>'gzip'));
        return resultArray(['data' => json_decode($json)]);
    }

    public function retransfer()
    {
        if (!$this->param['id']) {
            return resultArray(['error' => '参数错误']);
        }
        $result = $this->model->editSpeechtoReTransfer($this->param['id']);
        if ($result === false) {
            return resultArray(['error' => $this->model->getError()]);
        }
        return resultArray(['data' => '']);
    }

    public function getCharacterList($id)
    {
        try {
            $speech_model = $this->model->get($id);
            $content = json_decode($speech_model['editor'] ? $speech_model['editor'] : $speech_model['transfer'], true)['list'];
            $character_arr = array();
            foreach ($content as $value) {
                if (!in_array($value['speaker'], $character_arr)) {
                    array_push($character_arr, $value['speaker']);
                }
            }
            foreach ($character_arr as &$value) {
                $value = ['speaker' => $value];
            }
            return resultArray(['data' => ['list' => $character_arr]]);
        } catch (\Exception $e) {
            //return resultArray(['error' => $e->getMessage()]);
            return resultArray(['error' => '请求错误']);
        }
    }

    public function modifyCharacterList($id, $old, $new)
    {
        try {
            $speech_model = $this->model->get($id);
            $old = trim($old);
            $new = trim($new);
            $speech_model->transfer = str_replace("\"speaker\":\"$old\"", "\"speaker\":\"$new\"", $speech_model->transfer);
            $speech_model->editor = str_replace("\"speaker\":\"$old\"", "\"speaker\":\"$new\"", $speech_model->editor);
            $speech_model->save();
            return resultArray(['data' => ""]);
        } catch (\Exception $e) {
            //return resultArray(['error' => $e->getMessage()]);
            return resultArray(['error' => '请求错误']);
        }
    }

    public function modifyCharacterSingle($id, $num, $speaker)
    {
        try {
            $speaker = trim($speaker);
            $speech_model = $this->model->get($id);
            $transfer = json_decode($speech_model->transfer, true)['list'];
            $transfer[$num]['speaker'] = $speaker;
            $speech_model->transfer = json_encode(['list' => $transfer], JSON_UNESCAPED_UNICODE);
            $editor = json_decode($speech_model->editor, true)['list'];
            $editor[$num]['speaker'] = $speaker;
            $speech_model->editor = json_encode(['list' => $editor], JSON_UNESCAPED_UNICODE);
            $speech_model->save();
            return resultArray(['data' => ""]);
        } catch (\Exception $e) {
            //return resultArray(['error' => $e->getMessage()]);
            return resultArray(['error' => '请求错误']);
        }
    }

    public function selectCharacterSingleSpeech($id, $speaker)
    {
        try {
            if (!$id) {
                return resultArray(['error' => '参数错误']);
            }
            $result = $this->model->getDetail($this->param['id']);
            if (!$result) {
                return resultArray(['error' => $this->model->getError()]);
            }
            $data['lvsr_data'] = array_map(function ($data) use ($speaker) {
                if ($data['speaker'] != $speaker) {
                    $data['sc'] = '';
                }
                return $data;
            }, $result['lvsr_data']);
            //这一步是为了符合前端代码以后可以不用
            $i = 0;
            foreach ($data['lvsr_data'] as &$v) {
                $v['time'] = $i++;
            }
            return resultArray(['data' => $data]);
        } catch (\Exception $e) {
            //return resultArray(['error' => $e->getMessage()]);
            return resultArray(['error' => '请求错误']);
        }
    }

    public function getFileCount($uid)
    {
        $totle = $this->model->where(['is_delete' => 0, 'uid' => $uid])->count();
        return resultArray(['data' => ['total' => $totle]]);
    }

    //开始说话人分离功能
    public function startRoleSeparate($fid, $num = 2)
    {
        try{
            Db::startTrans();
            $param = [
                'fid' => $fid,
                'num' => $num,
            ];
            if($res = Db::name('separate_to_file')->where($param)->find()){
                $result = Db::name('separate_to_file')->where($param)->where('status','<>',0)->update(['status' => 0, 'separate' => '']);
                $id = $res['id'];
                if(!$result){
                    Db::commit();
                    return resultArray(['data' => ""]);
                }
            }else{
                $param['separate'] = '';
                $id = Db::name('separate_to_file')->insertGetId($param);
            }
            $speech = $this->model->get($fid);
            $role_arr = [
                'type' => 1,
                'id' => $id,
                'fid' => $fid,
                'num' => $num,
                'file' => config('huisheng.box_audio_dir') . DS . $speech->formatname . ".wav",
            ];
            self::$redis->roleSeparatePush($role_arr);
            Db::commit();
            return resultArray(['data' => ""]);
        }catch(\Exception $e){
            Db::rollback();
            return resultArray(['error' => $e->getMessage()]);
        }
    }

    //获取角色分离内容
    // public function separateShow($fid, $num = 2)
    // {
    //     $result = [];
    //     $separate = Model('SeparateToFile')->get(['fid' => $fid, 'num' => $num]);
    //     if (!$separate) {
    //         return resultArray(['data' => '']);
    //     }
    //     $speech = Model('LiveSpeech1')->get($fid);
    //     if($separate->separate){
    //         $result['separate'] = (new MixDataHandle($speech, $separate))->start();
    //         for ($i = 0; $i < count($result['separate']); $i++) {
    //             $result['separate'][$i]['id'] = $i;
    //         }
    //     }
    //     $result['status'] = $separate->status;
    //     return resultArray(['data' => $result]);
    // }

    public function separateShow($fid, $num = 2)
    {
        $result = [];
        $separate = Model('SeparateToFile')->get(['fid' => $fid, 'num' => $num]);
        if (!$separate) {
            return resultArray(['data' => '']);
        }
        if($separate->separate){
            $contents = file_get_contents($separate->separate);
            $filecontent = new Content();
            $FRAME = 0.2;
            $speech_list = json_decode($contents, true)['list'];
            if (!$speech_list) {
                $speech_list = [];
            }
            foreach ($speech_list as $sentence) {
                $filecontent->push($sentence['txt'], (explode("-", $sentence['time'])[1] - explode("-", $sentence['time'])[0]) * $FRAME, $sentence['speaker']);
            }
            $result['separate'] = $filecontent->paragraph()->getArr();
            // for ($i = 0; $i < count($result['separate']); $i++) {
            //     $result['separate'][$i]['id'] = $i;
            // }
            //过滤空语音
            $temp = [];
            for ($i = 0, $j=0; $i < count($result['separate']); $i++) {
                if($result['separate'][$i]['txt']){
                    $result['separate'][$i]['id'] = $j++;
                    array_push($temp, $result['separate'][$i]);
                }
            }
            $result['separate'] = $temp;
        }
        $result['status'] = $separate->status;
        return resultArray(['data' => $result]);
    }
}
